package com.cgy.utils.cmd.nets;


import com.cgy.utils.cmd.cmd.CmdHelper;
import com.cgy.utils.cmd.contants.Patterns;
import com.cgy.utils.cmd.contants.Systems;
import com.cgy.utils.cmd.utils.PatternUtils;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

/***
 * 网络工具类
 * @author CHTK
 */
public class Nets {
    /**
     * ping
     *
     * @param domainOrIp
     * @return
     */
    public static String ping(String domainOrIp) {
        return ping(domainOrIp, 3 * 1000, true);
    }

    /**
     * ping
     *
     * @param domainOrIp
     * @return
     */
    public static String ping(String domainOrIp, int timeout, boolean isReachable) {
        boolean reachable = false;
        try {
            reachable = InetAddress.getByName(domainOrIp).isReachable(timeout);
        } catch (IOException e) {
            // e.printStackTrace();
        }
        if (reachable == isReachable) {
            return domainOrIp;
        }
        return null;
    }

    /**
     * 获取局域网有效ip
     *
     * @return
     */
    public static List<String> localNetwork() {
        List<String> result = new ArrayList<>();
        InetAddress localHost;
        try {
            localHost = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            return result;
        }

        String hostAddress = localHost.getHostAddress();
        hostAddress = hostAddress.substring(0, hostAddress.lastIndexOf("."));

        ExecutorService executorService = new ThreadPoolExecutor(20, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());

        List<Future<String>> lFuture = new ArrayList<>();

        for (int i = 1; i < 255; i++) {
            String finalHostAddress = hostAddress;
            int finalI = i;
            lFuture.add(executorService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    String ping = ping(finalHostAddress + "." + finalI, 30, false);
                    return ping;
                }
            }));
        }

        for (Future<String> stringFuture : lFuture) {
            try {
                result.add(stringFuture.get());
            } catch (Exception e) {
            }
        }

        return result;

    }

    /**
     * 获取所有端口
     * @return
     */
    public static final List<String> posts() {
        if (Systems.isWin()) {
            String line = CmdHelper.commandLine("netstat -ano");
            return translate(line, "\r\n", true);
        } else if (Systems.isLinux()) {
            CmdHelper.commandLine("netstat -");
        }
        return Collections.emptyList();
    }
    /**
     * 获取所有任务
     * @return
     */
    public static final void tasklist() {
        if (Systems.isWin()) {
           CmdHelper.commandLine("tasklist");
        } else if (Systems.isLinux()) {
           CmdHelper.commandLine("netstat -");
        }
    }

    /**
     * 数据转化
     * @param line
     * @return
     */
    private static final List<String> translate(String line, String separator, boolean needIp) {
        List<String> result = new ArrayList<>();
        List<String> splitToList = Arrays.asList( line.split(separator));
        for (String s : splitToList) {
            boolean container = true;
            if(needIp) {
                container = PatternUtils.isContainer(s, Patterns.IP);
            }
            if (container) {
                List<String> matchPart = PatternUtils.getMatchPart(s, Patterns.PORT);
                for (String s1 : matchPart) {
                    s1 = s1.replace(":", "");
                    if(!"".equals(s1) && !"0".equals(s1)) {
                        result.add(s1);
                    }
                }
            }
        }
        return result;
    }

    public static void main(String[] args) throws IOException {
        tasklist();
    }

}
